package com.fessc.develop.handler.processor.send;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fessc.develop.entity.ccbvo.*;
import com.fessc.develop.entity.dbvo.*;
import com.fessc.develop.model.enums.*;
import com.fessc.develop.service.interfaces.*;
import com.fessc.develop.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 建行通用处理器，用于推送预付款信息/跨境付汇处理信息
 */

@Slf4j
@Service
public class CCBSendProcessor implements CCBISendProcessor {

    @Resource
    private ITOrgUrlManageService tOrgUrlManageService;

    @Resource
    private ITPaymentService paymentService;

    @Resource
    private ISettleTradeService settleTradeService;

    @Resource
    private ISettleTradeListService settleTradeListService;

    @Resource
    private ITCheckResultService checkRecordService;

    @Resource
    private ITCheckDetailService checkDetailService;

    @Resource
    private BankCheckResultService bankCheckResultService;

    @Resource
    private ITOrgConfigService orgConfigService;

    @Resource
    private OkHttpUtil okHttpUtil;

    /**
     * 建行预付款信息推送
     */
    @Override
    public void prePaymentProcess(List<TPayment> tPaymentList) {
        for (TPayment tPayment : tPaymentList) {
            try {
                //组装报文
                CCBPrePaymentBodyVo bodyVo = paymentService.fakeCCBPrePaymentSendBody(tPayment, "1");  //业务类型：1-订单扣款；2-订单退款
                String requestBody = getSendBodyData(bodyVo, EnumServiceCode.CCB_HMT003.toString());
                log.info("建行预付款请求报文：" + requestBody);
                String updatePaymentStatus = "";

                // 如果系统允许多个定时任务同时运行，或者多个线程运行，可能存在同一条待发送银行的记录在不同的定时任务中
                // 因此这里增加判断，如果该记录状态已经发送改变，可能是已发送银行，甚至都可能已经成功，那么该记录不再发送
                TPayment dbPayment = paymentService.getById(tPayment.getId());
                log.info("该笔预付款数据库当前状态：" + dbPayment.getSuborderno() + "，paymentStatus：" + dbPayment.getPaymentStatus() + "，paymentType：" + dbPayment.getPaymentType());
                if (BusiUtil.isNotEquals(dbPayment.getPaymentStatus(), "B") || BusiUtil.isNotEquals(dbPayment.getPaymentType(), "B")) {
                    log.info("该笔预付款数据库状态已经更改，不再发送至建行：" + tPaymentList.get(0).getSuborderno());
                    return;
                }

                //根据机构查询配置表获取URL,通用默认一个机构只有一个URL
                String url = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(tPayment.getBankid().toString(), EnumOrgType.BANK.toString(), EnumTaskCode.CCB_PRE_PAYMENT_PUSH.toString()).getInterfaceUrl();

                //接口推送
                String responseBody = okHttpUtil.doPostJson(url, requestBody);
                log.info("建行预付款返回报文：" + responseBody);

                //todo:根据返回处理剩余逻辑,调用成功，则更新paymentStatus
                //先按自己定义的返回来做通用处理
                JSONObject jsonObject = JSONObject.parseObject(responseBody);
                String paymentStatus = getPaymentStatusByJsonObject(responseBody, EnumTaskCode.CCB_PRE_PAYMENT_STATUS_PUSH.toString());
                if (BusiUtil.isEquals(EnumResultType.CCB_SEND.getStatusCode(), paymentStatus)) {
                    //建行异步接口，返回交易重复，将该笔交易状态修改为已发送银行，payment_status更改为send
                    log.info("建行预付款返回处理成功，修改状态为已发送银行：" + tPayment.getSuborderno());
                    updatePaymentStatus = EnumPaymentStatus.SEND.toString();
                    tPayment.setPaymentStatus(EnumPaymentStatus.SEND.toString());
                } else if (BusiUtil.isEquals(EnumResultType.CCB_FAIL.getStatusCode(), paymentStatus)) {
                    //建行异步接口，返回失败，将失败的状态码更新到payment_status，并将失败原因更新到payment_log
                    updatePaymentStatus = EnumPaymentStatus.PAYMENT_FAIL.toString();
                    log.info("建行预付款返回处理失败，修改状态为失败：" + tPayment.getSuborderno());
                    tPayment.setPaymentStatus(EnumResultType.CCB_FAIL.getStatusCode());
                    tPayment.setPaymentLog(BusiUtil.nvl(jsonObject.getJSONObject("body").getString("FalRs"), EnumPaymentStatus.PAYMENT_FAIL_LOG.toString()));
                } else {
                    //返回报文没有明确的交易状态，不更新交易状态，系统再次发起
                    log.info("建行预付款已经发送银行，但未返回明确交易状态，不更新交易状态：" + tPayment.getSuborderno());
                    continue;
                }

                // 更新交易状态，建行异步接口，只有发送银行或者失败，只有交易状态查询或者回调通知才会返回最终状态
                if (BusiUtil.isNotNull(updatePaymentStatus)) {
                    paymentService.updatePrePaymentStatusRefidsLog(tPayment, updatePaymentStatus);
                }

            } catch (Exception e) {
                log.info("建行预付款交易发生异常：" + e.getMessage());
            }
        }
    }

    /**
     * 建行预付款款退款推送
     *
     * @param tPaymentList 预付款集合
     */
    @Override
    public void prePaymentRefundProcess(List<TPayment> tPaymentList) {
        for (TPayment tPayment : tPaymentList) {
            try {
                //组装报文
                CCBPrePaymentBodyVo bodyVo = paymentService.fakeCCBPrePaymentRefundSendBody(tPayment, "2");
                String requestBody = getSendBodyData(bodyVo, EnumServiceCode.CCB_HMT003.toString());
                log.info("建行预付款退款请求报文：" + requestBody);
                String updatePaymentStatus = "";

                // 如果系统允许多个定时任务同时运行，或者多个线程运行，可能存在同一条待发送银行的记录在不同的定时任务中
                // 因此这里增加判断，如果该记录状态已经发送改变，可能是已发送银行，甚至都可能已经成功，那么该记录不再发送
                TPayment dbPayment = paymentService.getById(tPayment.getId());
                log.info("该笔预付款退款数据库当前状态：" + dbPayment.getSuborderno() + "，refund：" + dbPayment.getRefund() + "，paymentType：" + dbPayment.getPaymentType() + "，verifyStatus：" + dbPayment.getVerifyStatus());
                if (BusiUtil.isNotEquals(dbPayment.getRefund(), "Y") || BusiUtil.isNotEquals(dbPayment.getPaymentType(), "B") || BusiUtil.isNotEquals(dbPayment.getVerifyStatus(), "N")) {
                    log.info("该笔预付款退款数据库状态已经更改，不再发送至建行：" + tPaymentList.get(0).getSuborderno());
                    return;
                }

                //根据机构查询配置表获取URL,通用默认一个机构只有一个URL
                String url = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(tPayment.getBankid().toString(), EnumOrgType.BANK.toString(), EnumTaskCode.CCB_PRE_PAYMENT_PUSH.toString()).getInterfaceUrl();

                //接口推送
                String responseBody = okHttpUtil.doPostJson(url, requestBody);
                log.info("建行预付款退款返回报文：" + responseBody);

                //todo:根据返回处理剩余逻辑,调用成功，则更新paymentStatus
                //先按自己定义的返回来做通用处理
                JSONObject jsonObject = JSONObject.parseObject(responseBody);
                String paymentStatus = getPaymentStatusByJsonObject(responseBody, EnumTaskCode.CCB_PRE_PAYMENT_REFUND_PUSH.toString());
                if (BusiUtil.isEquals(EnumResultType.CCB_SEND.getStatusCode(), paymentStatus)) {
                    //建行异步接口，返回成功，将该笔交易状态verify_status修改为已发送银行Y
                    updatePaymentStatus = EnumPaymentStatus.SEND.toString();
                    log.info("建行预付款退款返回处理成功，修改状态为已发送银行：" + tPayment.getSuborderno());
                    tPayment.setVerifyStatus(EnumPaymentStatus.REFUND_SEND.toString());
                } else if (BusiUtil.isEquals(EnumResultType.CCB_FAIL.getStatusCode(), paymentStatus)) {
                    //建行异步接口，返回失败，将失败的状态码更新到refund_status，并将失败原因更新到refund_log，同时将该笔交易状态verify_status修改为已发送银行Y
                    updatePaymentStatus = EnumPaymentStatus.PAYMENT_FAIL.toString();
                    log.info("建行预付款退款返回处理失败，修改状态为失败：" + tPayment.getSuborderno());
                    tPayment.setVerifyStatus(EnumPaymentStatus.REFUND_SEND.toString());
                    tPayment.setRefundStatus(EnumResultType.CCB_FAIL.getStatusCode());
                    tPayment.setRefundLog(BusiUtil.nvl(jsonObject.getJSONObject("body").getString("FalRs"), EnumPaymentStatus.PAYMENT_FAIL_LOG.toString()));
                } else {
                    //返回报文没有明确的交易状态，不更新交易状态，系统再次发起
                    log.info("建行预付款退款已经发送银行，但未返回明确交易状态，不更新交易状态：" + tPayment.getSuborderno());
                    continue;
                }

                // 更新交易状态，建行异步接口，只有发送银行或者失败，只有交易状态查询或者回调通知才会返回最终状态
                if (BusiUtil.isNotNull(updatePaymentStatus)) {
                    paymentService.updateRefundStatusRefidsLog(tPayment, updatePaymentStatus);
                }

            } catch (Exception e) {
                log.info("建行预付款退款交易发生异常：" + e.getMessage());
            }
        }
    }

    /**
     * 建行跨境付汇推送
     */
    @Override
    public void settleTradeProcess(List<SettleTrade> settleTrades) {
        for (SettleTrade settleTrade : settleTrades) {
            try {
                //组装报文
                CCBSettleTradeSendBodyVo bodyVo = settleTradeService.fakeCCBSettleTradeSendBody(settleTrade);
                String requestBody = getSendBodyData(bodyVo, EnumServiceCode.CCB_HMT004.toString());
                log.info("建行跨境付汇请求报文：" + requestBody);
                String updatePaymentStatus = "";

                // 如果系统允许多个定时任务同时运行，或者多个线程运行，可能存在同一条待发送银行的记录在不同的定时任务中
                // 因此这里增加判断，如果该记录状态已经发送改变，可能是已发送银行，甚至都可能已经成功，那么该记录不再发送
                SettleTrade dbSettleTrade = settleTradeService.getById(settleTrade.getId());
                log.info("该笔跨境付汇数据库当前状态：" + dbSettleTrade.getOrderno() + "，reviewStatus：" + dbSettleTrade.getReviewStatus() + "，orderStatus：" + dbSettleTrade.getOrderStatus() + "，paymentType：" + dbSettleTrade.getPaymentType() + "，paymentTypeSend：" + dbSettleTrade.getPaymentTypeSend());
                if (BusiUtil.isNotEquals(dbSettleTrade.getReviewStatus(), "0") || BusiUtil.isNotEquals(dbSettleTrade.getOrderStatus(), "Y") || BusiUtil.isNotEquals(dbSettleTrade.getPaymentType(), "B") || BusiUtil.isNotEquals(dbSettleTrade.getPaymentTypeSend(), "N")) {
                    log.info("该笔跨境付汇数据库状态已经更改，不再发送至建行：" + settleTrade.getOrderno());
                    continue;
                }

                //根据机构查询配置表获取URL,通用默认一个机构只有一个URL
                String url = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(settleTrade.getBankid().toString(), EnumOrgType.BANK.toString(), EnumTaskCode.CCB_SETTLE_TRADE_PUSH.toString()).getInterfaceUrl();

                //接口推送
                String responseBody = okHttpUtil.doPostJson(url, requestBody);
                log.info("建行跨境付汇返回报文：" + responseBody);

                //todo:根据返回处理剩余逻辑,调用成功，则更新paymentStatus
                //先按自己定义的返回来做通用处理
                JSONObject jsonObject = JSONObject.parseObject(responseBody);
                String paymentStatus = getPaymentStatusByJsonObject(responseBody, EnumTaskCode.CCB_SETTLE_TRADE_PUSH.toString());
                if (BusiUtil.isEquals(EnumResultType.CCB_SEND.getStatusCode(), paymentStatus)) {
                    //建行异步接口，返回交易成功，将该笔交易状态修改为已发送银行，payment_type_send更改为Y
                    log.info("建行跨境付汇返回处理成功，修改状态为已发送银行：" + settleTrade.getOrderno());
                    updatePaymentStatus = EnumPaymentStatus.SEND.toString();
                    settleTrade.setPaymentTypeSend(EnumPaymentStatus.SETTLE_TRADE_SEND.toString());
                } else if (BusiUtil.isEquals(EnumResultType.CCB_FAIL.getStatusCode(), paymentStatus)) {
                    //建行异步接口，返回失败，将 review_status更改为3，reject_date为当前时间，reject_performer为银行直连机构号，
                    //remark 更改为银行返回的驳回原因，cancel_send更改为N，payment_type_send更改为Y
                    log.info("建行跨境付汇返回处理失败，修改状态为失败：" + settleTrade.getOrderno());
                    updatePaymentStatus = EnumPaymentStatus.PAYMENT_FAIL.toString();
                    settleTrade.setPaymentTypeSend(EnumPaymentStatus.SETTLE_TRADE_SEND.toString());
                    settleTrade.setReviewStatus(EnumPaymentStatus.SETTLE_REVIEW_FAIL.toString());
                    settleTrade.setRejectDate(DateUtil.getCurrentLocalDateTime());
                    settleTrade.setRejectPerformer(settleTrade.getOrgCode());
                    settleTrade.setRemark("银行驳回交易失败原因：" + BusiUtil.nvl(jsonObject.getJSONObject("head").getString("RstDsc"), jsonObject.getJSONObject("body").getString("FalRs")));
                    settleTrade.setCancelSend(EnumPaymentStatus.SETTLE_CANCEL_SEND.toString());
                } else {
                    //返回报文没有明确的交易状态，不更新交易状态，系统再次发起
                    log.info("建行跨境付汇已经发送银行，但未返回明确交易状态，不更新交易状态：" + settleTrade.getOrderno());
                    continue;
                }

                // 更新交易状态，建行异步接口，只有发送银行或者失败，只有交易状态查询或者回调通知才会返回最终状态
                if (BusiUtil.isEquals(EnumPaymentStatus.SEND.toString(), updatePaymentStatus)) {
                    log.info("更新建行跨境付汇状态已发送银行：" + settleTrade.getOrderno());
                    settleTradeService.updateSettleTradeStatusRefidsLog(settleTrade, updatePaymentStatus); //更新交易发送银行状态
                } else if (BusiUtil.isEquals(EnumPaymentStatus.PAYMENT_FAIL.toString(), updatePaymentStatus)) {
                    log.info("更新建行跨境付汇订单状态为失败：" + settleTrade.getOrderno());
                    settleTradeService.updateSettleTradeStatusRefidsLog(settleTrade, updatePaymentStatus); //更新交易失败状态
                    log.info("更新建行跨境付汇明细状态为失败：" + settleTrade.getOrderno());
                    settleTradeListService.updateSettleTradeListStatusBySettleId(settleTrade.getSettleId(), "N");
                }

            } catch (Exception e) {
                log.info("建行跨境付汇交易发生异常：" + e.getMessage());
            }
        }
    }

    /**
     * 预付款交易状态查询推送
     *
     * @param tPaymentList 预付款集合
     */
    @Override
    public void prePaymentStatusProcess(List<TPayment> tPaymentList) {
        for (TPayment tPayment : tPaymentList) {
            try {
                //组装报文
                CCBPrePaymentRefundStatusVo bodyVo = new CCBPrePaymentRefundStatusVo();
                BeanUtils.copyProperties(tPayment, bodyVo);
                String requestBody = getSendBodyData(bodyVo, EnumServiceCode.CCB_HMT007.toString());
                log.info("建行预付款交易状态查询请求报文：" + requestBody);
                String updatePaymentStatus = "";

                //根据机构查询配置表获取URL,通用默认一个机构只有一个URL
                String url = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(tPayment.getBankid().toString(), EnumOrgType.BANK.toString(), EnumTaskCode.CCB_PRE_PAYMENT_STATUS_PUSH.toString()).getInterfaceUrl();

                //接口推送
                String responseBody = okHttpUtil.doPostJson(url, requestBody);
                log.info("建行预付款交易状态查询返回报文：" + responseBody);

                //todo:根据返回处理剩余逻辑,调用成功，则更新paymentStatus
                //先按自己定义的返回来做通用处理
                JSONObject jsonObject = JSONObject.parseObject(responseBody);
                String rstCode = jsonObject.getJSONObject("head").getString("RstCode");  //银行返回报文状态，00:成功，01:失败
                String resTime = jsonObject.getJSONObject("head").getString("ResTime");  //报文返回时间，即银行预付款扣款时间
                String dedRlt = jsonObject.getJSONObject("body").getString("DedRlt");
                if (BusiUtil.isNotNull(jsonObject) && BusiUtil.isEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), rstCode)) {
                    if (BusiUtil.isEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), dedRlt)) {
                        //建行预付款交易状态查询返回交易成功，将0000回写到payment_status同时将“交易成功”回写到payment_log，将银行扣款流水号回写至bank_refids
                        log.info("建行预付款交易状态查询返回交易成功：" + tPayment.getSuborderno());
                        updatePaymentStatus = EnumPaymentStatus.PAYMENT_SUCCESS.toString();
                        tPayment.setPaymentStatus(EnumPaymentStatus.PAYMENT_SUCCESS.toString());
                        tPayment.setPaymentLog(EnumPaymentStatus.PAYMENT_SUCCESS_LOG.toString());
                        tPayment.setPaymentWorkdate(resTime);
                        tPayment.setBankRefids(jsonObject.getJSONObject("body").getString("DedScssTraceId"));
                    } else if (BusiUtil.isEquals(EnumResultType.CCB_FAIL.getStatusCode(), dedRlt)) {
                        //建行预付款交易状态查询返回交易失败，将失败的状态码回写到payment_status并将失败原因回写到payment_log
                        log.info("建行预付款交易状态查询返回交易失败：" + tPayment.getSuborderno());
                        updatePaymentStatus = EnumPaymentStatus.PAYMENT_FAIL.toString();
                        tPayment.setPaymentStatus(EnumResultType.CCB_FAIL.getStatusCode());
                        tPayment.setPaymentLog(BusiUtil.nvl(jsonObject.getJSONObject("body").getString("TxnRltDsc"), EnumPaymentStatus.PAYMENT_FAIL_LOG.toString()));
                    } else {
                        //收到返回成功报文，但是状态不是00成功，也不是01失败，不处理
                        log.info("建行预付款交易状态查询未返回最终状态：" + tPayment.getSuborderno());
                    }
                } else if (BusiUtil.isNotNull(jsonObject) && BusiUtil.isNotEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), rstCode)) {
                    //建行预付款交易状态返回报文格式错误
                    log.info("建行预付款交易状态查询返回报文格式错误：" + tPayment.getSuborderno());
                } else {
                    //建行预付款交易状态报文处理超时
                    log.info("建行预付款交易状态查询返回报文处理超时：" + tPayment.getSuborderno());
                }
                //返回交易最终状态成功或者失败，更新交易状态
                if (BusiUtil.isNotNull(updatePaymentStatus)) {
                    paymentService.updatePrePaymentStatusRefidsLog(tPayment, updatePaymentStatus); //更新发送银行状态
                }
            } catch (Exception e) {
                log.info("建行预付款交易状态交易发生异常：" + e.getMessage());
            }
        }
    }

    /**
     * 预付款退款状态推送处理
     *
     * @param tPaymentList 预付款集合
     */
    @Override
    public void prePaymentRefundStatusProcess(List<TPayment> tPaymentList) {
        for (TPayment tPayment : tPaymentList) {
            try {
                //组装报文
                CCBPrePaymentRefundStatusVo bodyVo = new CCBPrePaymentRefundStatusVo();
                BeanUtils.copyProperties(tPayment, bodyVo);
                String requestBody = getSendBodyData(bodyVo, EnumServiceCode.CCB_HMT007.toString());
                log.info("建行预付款退款交易状态查询请求报文：" + requestBody);
                String updatePaymentStatus = "";

                //根据机构查询配置表获取URL,通用默认一个机构只有一个URL
                String url = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(tPayment.getBankid().toString(), EnumOrgType.BANK.toString(), EnumTaskCode.CCB_PRE_PAYMENT_REFUND_STATUS_PUSH.toString()).getInterfaceUrl();

                //接口推送
                String responseBody = okHttpUtil.doPostJson(url, requestBody);
                log.info("建行预付款退款交易状态查询返回报文：" + responseBody);

                //todo:根据返回处理剩余逻辑,调用成功，则更新paymentStatus
                //先按自己定义的返回来做通用处理
                JSONObject jsonObject = JSONObject.parseObject(responseBody);
                String rstCode = jsonObject.getJSONObject("head").getString("RstCode");  //银行返回报文状态，00:成功，01:失败
                String resTime = jsonObject.getJSONObject("head").getString("ResTime");  //报文返回时间，即银行预付款退款时间
                String refdRlt = jsonObject.getJSONObject("body").getString("RefdRlt");
                if (BusiUtil.isNotNull(jsonObject) && BusiUtil.isEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), rstCode)) {
                    if (BusiUtil.isEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), refdRlt)) {
                        //建行预付款退款交易状态查询返回交易成功，将0000回写到refund_status同时将“交易成功”回写到refund_log，退款交易流水号回写到 refund_refids 同时将send2 更改成 N
                        updatePaymentStatus = EnumPaymentStatus.PAYMENT_SUCCESS.toString();
                        log.info("建行预付款退款交易状态查询返回交易成功：" + tPayment.getSuborderno());
                        tPayment.setRefundStatus(EnumPaymentStatus.PAYMENT_SUCCESS.toString());
                        tPayment.setRefundLog(EnumPaymentStatus.PAYMENT_SUCCESS_LOG.toString());
                        tPayment.setRefundRefids(jsonObject.getJSONObject("body").getString("RefdScssTraceId"));
                        tPayment.setRefundWorkdate(resTime);
                        tPayment.setSend2("N");
                    } else if (BusiUtil.isEquals(EnumResultType.CCB_FAIL.getStatusCode(), refdRlt)) {
                        //建行预付款退款交易状态查询返回交易失败，将失败的状态码回写到refund_status并将失败原因回写到refund_log
                        updatePaymentStatus = EnumPaymentStatus.PAYMENT_FAIL.toString();
                        log.info("建行预付款退款交易状态查询返回交易失败：" + tPayment.getSuborderno());
                        tPayment.setRefundStatus(EnumResultType.CCB_FAIL.getStatusCode());
                        tPayment.setRefundLog(BusiUtil.nvl(jsonObject.getJSONObject("body").getString("TxnRltDsc"), EnumPaymentStatus.PAYMENT_FAIL_LOG.toString()));
                    } else {
                        //收到返回成功报文，但是状态不是00成功，也不是01失败，不处理
                        log.info("建行预付款退款交易状态查询未返回最终状态：" + tPayment.getSuborderno());
                    }
                } else if (BusiUtil.isNotNull(jsonObject) && BusiUtil.isNotEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), rstCode)) {
                    //建行预付款交易状态返回报文格式错误
                    log.info("建行预付款退款交易状态查询返回报文格式错误：" + tPayment.getSuborderno());
                } else {
                    //建行预付款交易状态报文处理超时
                    log.info("建行预付款退款交易状态查询返回报文处理超时：" + tPayment.getSuborderno());
                }

                //返回交易最终状态成功或者失败，更新交易状态
                if (BusiUtil.isNotNull(updatePaymentStatus)) {
                    paymentService.updateRefundStatusRefidsLog(tPayment, updatePaymentStatus);
                }
            } catch (Exception e) {
                log.info("建行预付款退款交易状态交易发生异常：" + e.getMessage());
            }
        }
    }

    /**
     * 跨境付汇状态查询推送处理
     *
     * @param settleTrades 跨境付汇集合
     */
    @Override
    public void settleTradeStatusProcess(List<SettleTrade> settleTrades) {
        SettleTradeLoop:
        for (SettleTrade settleTrade : settleTrades) {
            try {
                //组装报文
                CCBSettleTradeSendBodyVo bodyVo = new CCBSettleTradeSendBodyVo();
                BeanUtils.copyProperties(settleTrade, bodyVo);
                String requestBody = getSendBodyData(bodyVo, EnumServiceCode.CCB_HMT008.toString());
                log.info("建行跨境付汇交易状态查询请求报文：" + requestBody);
                String updatePaymentStatus = "";

                //根据机构查询配置表获取URL,通用默认一个机构只有一个URL
                String url = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(settleTrade.getBankid().toString(), EnumOrgType.BANK.toString(), EnumTaskCode.CCB_SETTLE_TRADE_STATUS_PUSH.toString()).getInterfaceUrl();

                //接口推送
                String responseBody = okHttpUtil.doPostJson(url, requestBody);
                log.info("建行跨境付汇交易状态查询返回报文：" + responseBody);

                //todo:根据返回处理剩余逻辑,调用成功，则更新paymentStatus
                //先按自己定义的返回来做通用处理
                JSONObject jsonObject = JSONObject.parseObject(responseBody);
                String rstCode = jsonObject.getJSONObject("head").getString("RstCode");  //银行返回报文状态，00:成功，01:失败
                JSONArray ordrNos = jsonObject.getJSONObject("body").getJSONArray("OrdrNos");
                String totalCount = jsonObject.getJSONObject("body").getString("TotalCount");  //总笔数

                if (BusiUtil.isNotEquals(totalCount, String.valueOf(ordrNos.size()))) {
                    //返回总笔数与明细数组不一致
                    log.info("建行跨境付汇交易明细状态查询返回总笔数不一致：" + bodyVo.getOrderno());
                } else if (BusiUtil.isNotNull(jsonObject) && BusiUtil.isEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), rstCode)) {
                    List<SettleTradeList> settleTradeLists = new ArrayList<SettleTradeList>();
                    //循环判断返回订单明细状态，要么全部清算00-成功；01-失败，要么全部未清算02-未清算，不存在部分已经清算，部分未清算，因此可以根据明细清算结果判断订单是否清算完成
                    //如果已经清算，因为存在部分清算成功，部分失败的情况，因此订单状态只能改为成功，具体清算结果由明细的状态决定
                    for (int i = 0; i < ordrNos.size(); i++) {
                        SettleTradeList settleList = new SettleTradeList();
                        JSONObject obj = ordrNos.getJSONObject(i);
                        settleList.setSuborderno(obj.getString("OrdrNo"));
                        if (BusiUtil.isEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), obj.getString("TxnRlt"))) {
                            log.info("建行跨境付汇交易明细状态查询，交易成功：" + obj.getString("OrdrNo"));
                            settleList.setSerialnumberStatus(EnumResultType.CCB_SETTLE_TRADE_SUCCESS.getStatusCode());  //已跨境付汇
                            settleTradeLists.add(settleList);
                            updatePaymentStatus = EnumPaymentStatus.PAYMENT_SUCCESS.toString();
                        } else if (BusiUtil.isEquals(EnumResultType.CCB_FAIL.getStatusCode(), obj.getString("TxnRlt"))) {
                            log.info("建行跨境付汇交易明细状态查询，交易失败：" + obj.getString("OrdrNo"));
                            settleList.setSerialnumberStatus(EnumResultType.CCB_SETTLE_TRADE_FAIL.getStatusCode());  //未跨境付汇
                            settleTradeLists.add(settleList);
                            updatePaymentStatus = EnumPaymentStatus.PAYMENT_SUCCESS.toString();
                        } else {
                            log.info("建行跨境付汇交易明细状态查询，未返回最终状态：" + obj.getString("OrdrNo"));
                            //如果有未清算的明细，认为订单未清算，直接返回，不更改状态
                            continue SettleTradeLoop;
                        }
                    }

                    log.info("建行跨境付汇汇总订单交易状态查询，交易成功：" + settleTrade.getOrderno());
                    // 将review_status更改为2，deal_date为当前时间，deal_performer为银行直连机构号，review_date为当前时间
                    // 将review_performer为银行直连机构号，send2更改为N，serialnumber更改实际的跨境付款流水号
                    settleTrade.setReviewStatus(EnumPaymentStatus.SETTLE_REVIEW_SUCCESS.toString()); //银行审核付款成功
                    settleTrade.setDealDate(DateUtil.getCurrentLocalDateTime());  //当前时间
                    settleTrade.setDealPerformer(settleTrade.getOrgCode()); //银行直连机构号
                    settleTrade.setReviewDate(DateUtil.getCurrentLocalDateTime());  //当前时间
                    settleTrade.setReviewPerformer(settleTrade.getOrgCode());  //银行直连机构号
                    settleTrade.setSerialnumber(settleTrade.getSettleId());  //建行没有汇总订单的付款流水号，用settle_id代替
                    settleTrade.setSend2(EnumPaymentStatus.SETTLE_CANCEL_SEND.toString());

                    // 更新跨境订单交易表
                    log.info("更新建行跨境付汇订单状态为成功：" + settleTrade.getOrderno());
                    if (BusiUtil.isNotNull(settleTrade) && !settleTradeService.updateSettleTradeStatusRefidsLog(settleTrade, updatePaymentStatus)) {
                        throw ExceptionUtil.businessException("EE1004");
                    }
                    // 更新跨境订单明细表
                    log.info("更新建行跨境付订单汇明细状态：" + settleTrade.getOrderno());
                    if (BusiUtil.isNotNull(settleTradeLists) && !settleTradeListService.updateSettleTradeListStatusByOrderNo(settleTradeLists, settleTrade.getOrderno(), settleTrade.getSettleId())) {
                        throw ExceptionUtil.businessException("EE1004");
                    }

                } else if (BusiUtil.isNotNull(jsonObject) && BusiUtil.isNotEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), rstCode)) {
                    //建行跨境付订交易状态未返回最终状态
                    log.info("建行跨境付订交易状态查询未返回最终状态：" + bodyVo.getOrderno());
                } else {
                    //建行跨境付订交易状态报文处理超时
                    log.info("建行跨境付汇交易状态查询返回报文处理超时：" + bodyVo.getOrderno());
                }
            } catch (Exception e) {
                log.info("建行跨境付汇交易状态查询交易发生异常：" + e.getMessage());
            }
        }
    }

    /**
     * 对账推送-JSON格式
     *
     * @param ccbBankCheckJsonVoList 对账集合
     */
    @Override
    public void ccbBankCheckJsonProcess(List<CCBBankCheckJsonVo> ccbBankCheckJsonVoList) {
        for (CCBBankCheckJsonVo ccbBankCheckJsonVo : ccbBankCheckJsonVoList) {
            //组装报文
            CCBCommonSendHeadVo headVo = new CCBCommonSendHeadVo();
            headVo.setMsgBsnTp(EnumServiceCode.CCB_HMT009.toString());
            CCBCommonSendVo sendVo = new CCBCommonSendVo();
            sendVo.setCcbSendHeadVo(headVo);
            JSONObject ordrNoObject = new JSONObject();
            String checkDate = DateUtil.dateToString(ccbBankCheckJsonVo.getChectDate(), DateUtil.DATE_SIMP_FORMAT);
            ordrNoObject.put("Date", checkDate);
            ordrNoObject.put("Type", ccbBankCheckJsonVo.getType());
            String requestBody = JSON.toJSONString(sendVo);
            JSONObject reqObject = JSON.parseObject(requestBody);
            reqObject.put("body", ordrNoObject);
            LocalDateTime sendDateTime = DateUtil.getCurrentLocalDateTime();
            log.info("建行日终对账请求报文：" + reqObject.toString());

            //根据机构查询配置表获取URL,通用默认一个机构只有一个URL
            String url = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(ccbBankCheckJsonVo.getBankId(), EnumOrgType.BANK.toString(), EnumTaskCode.CCB_BANK_CHECK_PUSH.toString()).getInterfaceUrl();

            //接口推送
            String responseBody = okHttpUtil.doPostJson(url, reqObject.toJSONString());
            log.info("建行日终对账返回报文：" + responseBody);

            //todo:根据返回处理剩余逻辑,调用成功，则更新paymentStatus
            //先按自己定义的返回来做通用处理
            JSONObject jsonObject = JSONObject.parseObject(responseBody);
            String rstCode = jsonObject.getJSONObject("head").getString("RstCode");  //银行返回报文状态，00:成功，01:失败
            String rstDsc = jsonObject.getJSONObject("head").getString("RstDsc");  //建行返回系统级错误信息
            if (BusiUtil.isNotNull(jsonObject) && BusiUtil.isEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), rstCode)) {
                //日终对账明细
                JSONArray datalist = jsonObject.getJSONObject("body").getJSONArray("Datalist");
                //总笔数
                String totalCount = jsonObject.getJSONObject("body").getString("TotalCount");
                List<CCBCheckDetailVo> detailVoList = JSON.parseArray(datalist.toJSONString(), CCBCheckDetailVo.class);
                List<TCheckDetail> checkDetailList = new ArrayList<>();
                //循环解析日终对账明细
                detailVoList.forEach(detailVo -> {
                    TCheckDetail checkDetail = new TCheckDetail();
                    checkDetail.setSuborderno(detailVo.getOrdrNo());
                    if (BusiUtil.isEquals(ccbBankCheckJsonVo.getType(), EnumCheckType.PRE_PAYMENT_CHECK.toString())) {
                        //预付款日终对账
                        checkDetail.setBankStatus(detailVo.getTxnRlt());
                        checkDetail.setBankRefids(detailVo.getTxnScssTraceId());
                        checkDetail.setBankLog(detailVo.getTxnRltDsc());
                    } else {
                        //预付款退款日终对账
                        checkDetail.setBankStatus(detailVo.getTxnRlt());
                        checkDetail.setBankRefids(detailVo.getTxnScssTraceId());
                        checkDetail.setBankLog(detailVo.getTxnRltDsc());
                    }
                    checkDetail.setCheckDate(ccbBankCheckJsonVo.getChectDate());
                    checkDetail.setBatchNo(ccbBankCheckJsonVo.getBatchNo());
                    checkDetail.setCheckType(ccbBankCheckJsonVo.getType());
                    checkDetail.setEffectiveStatus("Y");
                    checkDetail.setTotalCount(totalCount);
                    checkDetail.setCheckTime(sendDateTime);
                    checkDetail.setBankId(ccbBankCheckJsonVo.getBankId());
                    checkDetailList.add(checkDetail);
                });
                //可能多次对账，因此先更新记录为失效状态，再保存最新记录
                log.info("更新日终对账结果为失效状态：" + checkDate);
                checkDetailService.updateCheckDetailByDate("N", ccbBankCheckJsonVo.getBankId(), ccbBankCheckJsonVo.getChectDate(), ccbBankCheckJsonVo.getType());
                //批量保存
                log.info("保存银行返回的日终对账结果：" + checkDate);
                checkDetailService.saveBatch(checkDetailList);

                //查询预付款对账不符合的数据
                List<TCheckDetail> paymentCheckResultList = new ArrayList<TCheckDetail>();
                if (BusiUtil.isEquals(EnumCheckType.PRE_PAYMENT_CHECK.toString(), ccbBankCheckJsonVo.getType())) {
                    log.info("查询预付款对账不符合的数据：" + checkDate);
                    paymentCheckResultList = checkDetailService.getPrePaymentResultByCheckDate(ccbBankCheckJsonVo.getBankId(), ccbBankCheckJsonVo.getChectDate(), ccbBankCheckJsonVo.getType());
                    log.info("互联互通与银行预付款对账：日期" + checkDate + "，批次号" + ccbBankCheckJsonVo.getBatchNo());
                    bankCheckResultService.checkPayment(paymentCheckResultList, ccbBankCheckJsonVo.getBankId(), ccbBankCheckJsonVo.getBatchNo());
                } else {
                    log.info("查询预付款退款对账不符合的数据：" + checkDate);
                    paymentCheckResultList = checkDetailService.getPrePaymentRefundResultByCheckDate(ccbBankCheckJsonVo.getBankId(), ccbBankCheckJsonVo.getChectDate(), ccbBankCheckJsonVo.getType());
                    log.info("互联互通与银行预付款退款对账：日期" + checkDate + "，批次号" + ccbBankCheckJsonVo.getBatchNo());
                    bankCheckResultService.checkRefund(paymentCheckResultList, ccbBankCheckJsonVo.getBankId(), ccbBankCheckJsonVo.getBatchNo());
                }

                log.info("保存预付款对账结果：" + checkDate);
                TCheckResult checkResult = new TCheckResult();
                if (paymentCheckResultList.isEmpty()) {
                    checkResult.setCheckResult("S");
                } else {
                    checkResult.setCheckResult("F");
                }
                checkResult.setBankId(ccbBankCheckJsonVo.getBankId());
                checkResult.setBatchNo(ccbBankCheckJsonVo.getBatchNo());
                checkResult.setCheckType(ccbBankCheckJsonVo.getType());
                checkResult.setCheckDate(ccbBankCheckJsonVo.getChectDate());
                checkResult.setCheckTime(sendDateTime);
                checkResult.setErrorNum(paymentCheckResultList.size());
                checkRecordService.save(checkResult);

                //循环解析对账不符明细
                /*
                List<TCheckResultList> checkResultListList = new ArrayList<>();
                paymentCheckResultList.forEach(detail -> {
                    String errorMsg = "";
                    // 错误类型0：状态不一致，1：互联互通有记录，银行未返回该记录，2：互联互通无记录，银行返回该记录
                    if (BusiUtil.isEquals(EnumCheckType.PRE_PAYMENT_CHECK.toString(), ccbBankCheckJsonVo.getType())) {
                        if (BusiUtil.isEquals(detail.getErrorType(), "0")) {
                            errorMsg = "预付款-互联互通与银行对账结果不一致，订单编号：" + detail.getSuborderno() + "，互联互通状态：" + detail.getStatus() + "，银行返回状态：" + detail.getBankStatus();
                            if (BusiUtil.isEquals(detail.getBankStatus(), EnumResultType.CHECK_BANK_SUCCESS.getStatusCode())) {
                                // 对账返回状态为交易成功，以对账结果为准，重新更新交易状态
                                log.info("预付款对账返回状态为交易成功，以对账结果为准，更新交易状态为成功：" + detail.getSuborderno());
                                TPayment tPayment = new TPayment();
                                tPayment.setSuborderno(detail.getSuborderno());
                                tPayment.setPaymentStatus(EnumPaymentStatus.PAYMENT_SUCCESS.toString());
                                tPayment.setPaymentLog(EnumPaymentStatus.PAYMENT_SUCCESS_LOG.toString());
                                tPayment.setBankRefids(detail.getBankRefids());
                                paymentService.updatePrePaymentStatusRefidsLog(tPayment, EnumPaymentStatus.PAYMENT_SUCCESS.toString());
                            } else if (BusiUtil.isEquals(detail.getBankStatus(), EnumResultType.CHECK_BANK_FAIL.getStatusCode())) {
                                // 对账返回状态为交易失败，以对账结果为准，重新更新交易状态
                                log.info("预付款对账返回状态为交易失败，以对账结果为准，更新交易状态为失败：" + detail.getSuborderno());
                                TPayment tPayment = new TPayment();
                                tPayment.setSuborderno(detail.getSuborderno());
                                tPayment.setPaymentStatus(EnumResultType.CHECK_BANK_FAIL.getStatusCode());
                                tPayment.setPaymentLog(BusiUtil.nvl(detail.getBankLog(), EnumPaymentStatus.PAYMENT_FAIL_LOG.toString()));
                                paymentService.updatePrePaymentStatusRefidsLog(tPayment, EnumPaymentStatus.PAYMENT_FAIL.toString());
                            }
                        } else if (BusiUtil.isEquals(detail.getErrorType(), "1")) {
                            errorMsg = "预付款-互联互通有记录，银行未返回对账结果，订单编号：" + detail.getSuborderno();
                        } else if (BusiUtil.isEquals(detail.getErrorType(), "2")) {
                            errorMsg = "预付款-互联互通无记录，银行有返回对账结果，订单编号：" + detail.getSuborderno();
                        }
                    } else {
                        if (BusiUtil.isEquals(detail.getErrorType(), "0")) {
                            errorMsg = "预付款退款-互联互通与银行对账结果不一致，订单编号：" + detail.getSuborderno() + "，互联互通状态：" + detail.getStatus() + "，银行返回状态：" + detail.getBankStatus();
                            if (BusiUtil.isEquals(detail.getBankStatus(), EnumResultType.CHECK_BANK_SUCCESS.getStatusCode())) {
                                // 对账返回状态为交易成功，以对账结果为准，重新更新交易状态
                                log.info("预付款退款对账返回状态为交易成功，以对账结果为准，更新交易状态为成功：" + detail.getSuborderno());
                                TPayment tPayment = new TPayment();
                                tPayment.setRefundStatus(EnumPaymentStatus.PAYMENT_SUCCESS.toString());
                                tPayment.setRefundLog(EnumPaymentStatus.PAYMENT_SUCCESS_LOG.toString());
                                tPayment.setRefundRefids(detail.getBankRefids());
                                tPayment.setSend2("N");
                                paymentService.updateRefundStatusRefidsLog(tPayment, EnumPaymentStatus.PAYMENT_SUCCESS.toString());
                            } else if (BusiUtil.isEquals(detail.getBankStatus(), EnumResultType.CHECK_BANK_FAIL.getStatusCode())) {
                                // 对账返回状态为交易失败，以对账结果为准，重新更新交易状态
                                log.info("预付款退款对账返回状态为交易失败，以对账结果为准，更新交易状态为失败：" + detail.getSuborderno());
                                TPayment tPayment = new TPayment();
                                tPayment.setRefundStatus(EnumResultType.CHECK_BANK_FAIL.getStatusCode());
                                tPayment.setRefundLog(BusiUtil.nvl(detail.getBankLog(), EnumPaymentStatus.PAYMENT_FAIL_LOG.toString()));
                                paymentService.updateRefundStatusRefidsLog(tPayment, EnumPaymentStatus.PAYMENT_FAIL.toString());
                            }
                        } else if (BusiUtil.isEquals(detail.getErrorType(), "1")) {
                            errorMsg = "预付款退款-互联互通有记录，银行未返回对账结果，订单编号：" + detail.getSuborderno();
                        } else if (BusiUtil.isEquals(detail.getErrorType(), "2")) {
                            errorMsg = "预付款退款-互联互通无记录，银行有返回对账结果，订单编号：" + detail.getSuborderno();
                        }
                    }
                    TCheckResultList checkResultList = new TCheckResultList();
                    checkResultList.setCheckDate(ccbBankCheckJsonVo.getChectDate());
                    checkResultList.setCheckType(ccbBankCheckJsonVo.getType());
                    checkResultList.setBatchNo(ccbBankCheckJsonVo.getBatchNo());
                    checkResultList.setBankId(ccbBankCheckJsonVo.getBankId());
                    checkResultList.setSuborderno(detail.getSuborderno());
                    checkResultList.setCheckLog(errorMsg);
                    checkResultList.setCheckTime(sendDateTime);
                    checkResultListList.add(checkResultList);
                    log.info("预付款对账结果不符信息：" + errorMsg);
                });
                log.info("保存预付款对账不符详细结果：" + checkDate);
                checkResultListService.saveBatch(checkResultListList);
                */
            } else {
                // 记录对账表
                log.info("银行返回对账失败，记录对账表：" + rstDsc);
                TCheckResult checkResult = new TCheckResult();
                checkResult.setCheckResult("E");
                checkResult.setBankId(ccbBankCheckJsonVo.getBankId());
                checkResult.setBatchNo(ccbBankCheckJsonVo.getBatchNo());
                checkResult.setCheckType(ccbBankCheckJsonVo.getType());
                checkResult.setCheckDate(ccbBankCheckJsonVo.getChectDate());
                checkResult.setCheckTime(sendDateTime);
                checkResult.setErrorLog(rstDsc);
                checkRecordService.save(checkResult);
            }
        }
    }

    /**
     * 组装银行发送报文
     *
     * @param sendBodyVo 发送报文
     */
    private String getSendBodyData(CCBCommonSendBodyVo sendBodyVo, String ServiceCode) {
        //组装报文
        CCBCommonSendHeadVo headVo = new CCBCommonSendHeadVo();
        CCBCommonSendVo sendVo = new CCBCommonSendVo();
        // 根据机构号查询互市点机构代码
        log.info("查询交易记录对应机构信息：" + sendBodyVo.getOrgCode());
        TOrgConfig orgConfig = orgConfigService.getOrgConfigByOrgCode(sendBodyVo.getOrgCode());
        if (BusiUtil.isNotNull(orgConfig.getOrgCode())) {
            headVo.setOrg(orgConfig.getExchangePlaceCode());  //互市点机构代码
            headVo.setCoPlfID(orgConfig.getPlatidS());  //服务商代码
        }
        headVo.setMsgBsnTp(ServiceCode);
        sendVo.setCcbSendHeadVo(headVo);
        sendVo.setCcbSendBodyVo(sendBodyVo);
        return JSON.toJSONString(sendVo);
    }

    /**
     * 判断交易状态，根据返回结果更新交易状态，返回空不进行任何处理，由系统重新推送至银行
     *
     * @param responseBody  返回报文
     * @param taskCode 定时任务
     */
    private String getPaymentStatusByJsonObject(String responseBody, String taskCode) {
        String retValue = "";
        JSONObject jsonObject = JSONObject.parseObject(responseBody);
        String rstCode = "";  //建行返回系统级报文状态，00:成功，01:失败
        String pcsgRlt = "";  //建行返回业务级报文状态，00:成功，01:失败
        try {
            rstCode = jsonObject.getJSONObject("head").getString("RstCode");
        } catch (Exception e) {
            log.info("解析返回报文head返回码异常：" + e.getMessage());
        }
        try {
            pcsgRlt = jsonObject.getJSONObject("body").getString("PcsgRlt");
        } catch (Exception e) {
            log.info("解析返回报文body返回码异常：" + e.getMessage());
        }

        // 交易状态判断逻辑，根据以下步骤进行
        // 1、建行预付款，预付款退款、跨境付汇都是异步，返回成功并非最终交易状态，需要通过交易状态查询接口更新最终交易状态
        // 2、首先根据head、body的返回错误信息判断，如果含有特定的重复标志（如重复，已存在等），该笔交易状态改为已经发送银行
        // 3、如果head返回码成功00，根据body的返回码判断，如果成功，该笔交易状态改为已经发送银行，如果失败，该笔交易状态改为失败
        // 4、如果head返回码失败01，该笔交易状态改为失败
        // 5、2和3不冲突，优先判断1，1不需要判断返回码，只判断错误信息，如果返回码为01失败并且错误信息，该交易优先改为已经发送银行，再根据结果查询接口查询最终状态
        try {
            if (checkRepeat(jsonObject, taskCode)) {  //根据错误信息判断是否重复
                log.info("交易状态：" + EnumResultType.CCB_REPEAT.getMsg());
                retValue = EnumResultType.CCB_SEND.getStatusCode();
            } else if (BusiUtil.isNotEquals(rstCode, EnumResultType.CCB_SUCCESS.getStatusCode()) && BusiUtil.isNotEquals(rstCode, EnumResultType.CCB_FAIL.getStatusCode())) {
                log.info("1-交易状态：未返回交易状态");
                retValue = "";
            } else if (BusiUtil.isEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), rstCode)) {  //返回系统级成功，即head返回成功
                if (BusiUtil.isEquals(EnumResultType.CCB_SUCCESS.getStatusCode(), pcsgRlt)) {
                    log.info("交易状态：" + EnumResultType.CCB_SEND.getMsg());
                    retValue = EnumResultType.CCB_SEND.getStatusCode();
                } else if (BusiUtil.isEquals(EnumResultType.CCB_FAIL.getStatusCode(), pcsgRlt)) {
                    log.info("交易状态：" + EnumResultType.CCB_FAIL.getMsg());
                    retValue = EnumResultType.CCB_FAIL.getStatusCode();
                } else {
                    //报文体body返回码为空
                    log.info("2-交易状态：未返回交易状态");
                    retValue = "";
                }
            } else if (BusiUtil.isNotNull(jsonObject) && BusiUtil.isEquals(EnumResultType.CCB_FAIL.getStatusCode(), rstCode)) {
                log.info("交易状态：" + EnumResultType.CCB_FAIL.getMsg());
                retValue = EnumResultType.CCB_FAIL.getStatusCode();
            } else {
                log.info("3-交易状态：未返回交易状态");
                retValue = "";
            }
        } catch (Exception e) {
            log.info("判断交易状态异常：" + e.getMessage());
        }
        return retValue;
    }

    /**
     * 判断订单是否重复，建行未返回重复标志，只能根据错误信息来判断
     * 预付款、退款判断规则：
     * 1、根据返回信息如[ERRORCODE=YBLA0332HG01] [错误描述@@订单号已存在，请勿重复推送订单@@]判断
     * 跨境付汇：
     * 1、根据返回信息如[ERRORCODE=YBLA0332HG01] [错误描述@@订单号已存在，请勿重复推送订单@@]判断
     * 2、根据返回码02，表示订重复交易
     *
     * @param responseBody 返回报文
     * @param taskCode 定时任务
     */
    private boolean checkRepeat(JSONObject responseBody, String taskCode) {
        boolean retValue = false;
        try {
            String rstCode = BusiUtil.nvl(responseBody.getJSONObject("head").getString("RstCode"), "");  //建行返回系统级报文状态，00:成功，01:失败
            String rstDsc = BusiUtil.nvl(responseBody.getJSONObject("head").getString("RstDsc"), "");    //建行返回系统级错误信息
            String pcsgRlt = BusiUtil.nvl(responseBody.getJSONObject("body").getString("PcsgRlt"), "");  //建行返回业务级报文状态，00:成功，01:失败，02重复（只有跨境付汇返回02，预付款不返回02）
            //根据建行返回系统级错误信息判断是否重复(head部分)
            if (BusiUtil.isEquals(taskCode, EnumTaskCode.CCB_SETTLE_TRADE_PUSH.toString()) && BusiUtil.isEquals(rstCode, EnumResultType.CCB_REPEAT.getStatusCode())) {
                // 跨境付汇返回码02重复交易
                retValue = true;
            } else if (BusiUtil.isEquals(taskCode, EnumTaskCode.CCB_SETTLE_TRADE_PUSH.toString()) && BusiUtil.isEquals(pcsgRlt, EnumResultType.CCB_REPEAT.getStatusCode())) {
                // 跨境付汇返回码02重复交易
                retValue = true;
            } else if (rstDsc.contains("已存在")) {
                retValue = true;
            } else if (rstDsc.contains("重复")) {
                retValue = true;
            } else {
                //根据建行返回业务级错误信息判断是否重复（body部分）
                String falRs = BusiUtil.nvl(responseBody.getJSONObject("body").getString("FalRs"), "");
                if (falRs.contains("已存在")) {
                    retValue = true;
                } else if (falRs.contains("重复")) {
                    retValue = true;
                }
            }
        } catch (Exception e) {
            log.info("判断是否重复交易异常：" + e.getMessage());
        }
        return retValue;
    }

    /**
     * 获取处理器类型
     *
     */
    @Override
    public String getProcessorForBranch() {

        return EnumBranch.CCBBANK.toString();
    }

}
